package com.ynet.middleground.contract.service.impl;

import java.util.List;
import java.util.Map;

import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import com.google.common.base.Throwables;
import com.ynet.core.common.ServiceResult;
import com.ynet.core.exception.BusinessException;
import com.ynet.core.log.IfpLogger;
import com.ynet.middleground.contract.bean.*;
import com.ynet.middleground.contract.model.EviModel;
import com.ynet.middleground.contract.service.EviService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

/**
 * @author liulx
 * @description 存证相关接口服务具体实现
 * @date 2020-04-15 14:01
 */
@Produces({MediaType.APPLICATION_JSON + "; " + "charset=UTF-8"})
@Consumes({MediaType.APPLICATION_JSON + "; " + "charset=UTF-8"})
@Api(value = "存证相关接口服务", tags = {"存证相关接口服务"})
@Path("evi")
@Service(timeout = 6000, version = "0.0.1")
public class EviServiceImpl implements EviService, GenericService {

    @Autowired
    EviModel eviModel;

    /**
     * 定义所属行业类型-数据字典，永久使用
     *
     * @param addIndustryTypeReq 定义行业所属类型请求类
     * @return 添加成功后 ID 和名称的对应列表
     */
    @POST
    @Path("industry-type")
    @ApiOperation(value = "定义所属行业类型", notes = "新增所属行业类型记录")
    @ApiImplicitParam(name = "requestObj", dataType = "AddIndustryTypeReq", paramType = "body", required = true)
    @Override
    public ServiceResult<Map<String, Object>> createIndustryType(@Valid AddIndustryTypeReq addIndustryTypeReq) {
        ServiceResult<Map<String, Object>> result = new ServiceResult<>();
        try {
            result.setResult(eviModel.createIndustryType(addIndustryTypeReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "新增所属行业类型服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 定义业务凭证（名称）
     *
     * @param addSceneTypeReq 定义业务凭证（名称）请求类
     * @return 添加成功后 ID 和名称的对应列表
     */
    @POST
    @Path("scene-type")
    @ApiOperation(value = "定义业务凭证（名称）", notes = "新增业务凭证（名称）记录，可理解成证据发生的场景，如房屋租赁合同签署")
    @ApiImplicitParam(name = "requestObj", dataType = "AddSceneTypeReq", paramType = "body", required = true)
    @Override
    public ServiceResult<Map<String, Object>> createSceneType(@Valid AddSceneTypeReq addSceneTypeReq) {
        ServiceResult<Map<String, Object>> result = new ServiceResult<>();
        try {
            result.setResult(eviModel.createSceneType(addSceneTypeReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "新增业务凭证（名称）服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 定义业务凭证中某一证据点名称 <br />
     * (如：治疗合同签署人信息)
     *
     * @param addSegmentTypeReq 定义业务凭证中某一证据点名称请求类
     * @return 添加成功后 ID 和名称的对应列表
     */
    @POST
    @Path("segment-type")
    @ApiOperation(value = "定义业务凭证中某一证据点名称", notes = "定义业务凭证中某一证据点名称，可理解成与证据发生时场景有关的信息，如治疗合同签署人信息")
    @ApiImplicitParam(name = "requestObj", dataType = "AddSegmentTypeReq", paramType = "body", required = true)
    @Override
    public ServiceResult<Map<String, Object>> createSegmentType(@Valid AddSegmentTypeReq addSegmentTypeReq) {
        ServiceResult<Map<String, Object>> result = new ServiceResult<>();
        try {
            result.setResult(eviModel.createSegmentType(addSegmentTypeReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "定义业务凭证中某一证据点名称服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 定义业务凭证中某一证据点的字段属性 <br />
     * (如：姓名-name) 设置显示名称与参数名称的对应关系
     *
     * @param addSegmentPropTypeReq 定义业务凭证中某一证据点的字段属性请求类
     * @return 添加成功后的对应列表
     */
    @POST
    @Path("segment-prop-type")
    @ApiOperation(value = "定义业务凭证中某一证据点的字段属性",
        notes = "定义业务凭证中某一证据点的字段属性，可理解成将与证据发生时场景有关的信息的字段属性进行设置，以便客户查询存证时能够清晰的观看相关信息，如合同签署人信息的姓名、身份证号、签署短信验证码等。")
    @ApiImplicitParam(name = "requestObj", dataType = "AddSegmentPropTypeReq", paramType = "body", required = true)
    @Override
    public ServiceResult<List<Object>> createSegmentProType(@Valid AddSegmentPropTypeReq addSegmentPropTypeReq) {
        ServiceResult<List<Object>> result = new ServiceResult<>();
        try {
            result.setResult(eviModel.createSegmentPropType(addSegmentPropTypeReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(),
                "定义业务凭证中某一证据点的字段属性服务异常, case: {}", Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 创建证据链,获取场景式存证编号（证据链编号）
     *
     * @param addChainOfEvidenceReq 创建证据链请求类
     * @return 场景式存证编号
     */
    @POST
    @Path("scene")
    @ApiOperation(value = "创建证据链，获取场景式存证编号（证据链编号）",
        notes = "新增一条证据链记录，并获取场景式存证编号，以便后期向该条证据链中继续追加证据点 \n 一条证据链上最多可追加50条证据点")
    @ApiImplicitParam(name = "requestObj", dataType = "AddChainOfEvidenceReq", paramType = "body", required = true)
    @Override
    public ServiceResult<String> createChainOfEvidence(@Valid AddChainOfEvidenceReq addChainOfEvidenceReq) {
        ServiceResult<String> result = new ServiceResult<>();
        try {
            result.setResult(eviModel.createChainOfEvidence(addChainOfEvidenceReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "创建证据链服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 创建摘要存证证据点
     *
     * @param addSegmentOriginalDigestReq 创建摘要存证证据点请求类
     * @return 摘要存证证据点 ID
     */
    @POST
    @Path("abstract")
    @ApiOperation(value = "创建摘要存证证据点",
        notes = "摘要版存证不会将原文进行推送,仅是将原文的摘要(SHA256)推送到e签宝服务端、司法鉴定中心（全称：国家信息中心电子数据司法鉴定中心）和公证处")
    @ApiImplicitParam(name = "requestObj", dataType = "AddSegmentOriginalDigestReq", paramType = "body",
        required = true)
    @Override
    public ServiceResult<String>
        createSegmentOriginalDigest(@Valid AddSegmentOriginalDigestReq addSegmentOriginalDigestReq) {
        ServiceResult<String> result = new ServiceResult<>();
        try {
            result.setResult(eviModel.createSegmentOriginalDigest(addSegmentOriginalDigestReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "创建证据链服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 追加证据点，将证据点追加到已存在的证据链内形成证据链
     *
     * @param appendEvidenceReq 追加证据点请求类
     * @return 结果标志，以 success 字段值标识 true/false
     */
    @POST
    @Path("append")
    @ApiOperation(value = "追加证据点", notes = "将证据点追加到已存在的证据链内形成证据链")
    @ApiImplicitParam(name = "requestObj", dataType = "AppendEvidenceReq", paramType = "body", required = true)
    @Override
    public ServiceResult appendEvidence(@Valid AppendEvidenceReq appendEvidenceReq) {
        ServiceResult result = new ServiceResult<>();
        try {
            eviModel.appendEvidence(appendEvidenceReq);
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "追加证据点服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 场景式存证编号(证据链编号)关联到指定的用户,以便指定用户日后可以顺利出证
     *
     * @param relateSceneEvIdWithUserReq 数据存证编号关联到指定用户请求类
     * @return 结果标志，以 success 字段值标识 true/false
     */
    @POST
    @Path("relate")
    @ApiOperation(value = "数据存证编号关联到指定用户", notes = "将场景式存证编号与用户的证件号进行关联后，在需要出证时该用户可登录e签宝官网进行在线申请")
    @ApiImplicitParam(name = "requestObj", dataType = "RelateSceneEvIdWithUserReq", paramType = "body", required = true)
    @Override
    public ServiceResult relateSceneEvIdWithUser(@Valid RelateSceneEvIdWithUserReq relateSceneEvIdWithUserReq) {
        ServiceResult result = new ServiceResult<>();
        try {
            eviModel.relateSceneEvIdWithUser(relateSceneEvIdWithUserReq);
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "数据存证编号关联到指定用户服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;
    }

    /**
     * 存证证明查看页面链接
     *
     * @param getEviViewPageUrlReq 存证证明查看页面链接请求类
     * @return 存证证明页面查看地址
     */
    @POST
    @Path("get-view-page")
    @ApiOperation(value = "存证证明查看页面链接", notes = "存证证明查看页面链接")
    @ApiImplicitParam(name = "requestObj", dataType = "GetEviViewPageUrlReq", paramType = "body", required = true)
    @Override
    public ServiceResult<String> getEviViewPageUrlReq(@Valid GetEviViewPageUrlReq getEviViewPageUrlReq) {
        ServiceResult<String> result = new ServiceResult<>();
        try {
            result.setResult(eviModel.getEviViewPageUrlReq(getEviViewPageUrlReq));
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "存证证明查看页面链接服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECCT0000", "服务异常，请联系系统管理员");
        }
        return result;

    }

}
